﻿using Kinlo.Entitys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UIWindows.GlobalStatics;
using UIWindows.Services.Context;
using UIWindows.Tools.Helper;
using XingLucifer.Devices;
using XingLucifer.Devices.Models;
using XingLucifer.IBase.Enums;

namespace UIWindows.Services.Handle
{
    [Attributes.TaskClass(TaskTypes.RJ6902R)]
    public class RJ6902RHandle : ServierBase
    {
        public RJ6902RHandle(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfig,
            UserConfigStatic userConfig, ParameterStatic parameterStatic, TemporaryStatic temporaryStatic, HomeStatic homeStatic, MesParameterStatic mesParameterStatic)
            : base(deviceConfig, systemConfig, userConfig, parameterStatic, temporaryStatic, homeStatic, mesParameterStatic)
        {

        }

        private volatile int _ngShortCircuit = 0;
        public override Task Handle(DataContext context)
        {
            try
            {
                if (!ClearSignal(context)) { return Task.CompletedTask; }
                _ngShortCircuit = 0;
                var plc = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == TaskTypes.扫描信号).Communication as OmronCIP;
                DateTime weighing_time = DateTime.Now;
                var erinnerungen = ReadErinnerungen(plc, context.Address_Struct, context.Struct_Length, _systemConfig.IAddress.Erinnerungen_Kurzschluss, context.AddressingMethod);
                if (erinnerungen.Item1)
                {
                    $"==>>{context.TaskType}<<==\r\n收到启动信号，没收到电池记忆，请联系电气工程师！！！".MessageDialogs(MessageLevelType.错误, false, Enums.PopUpTypes.Global);
                    return base.Handle(context);
                }
                RunLog($"记忆ID：{string.Join(";", erinnerungen.Item2.Select(x => x.SnowflakeId))}");
                Parallel.ForEach(erinnerungen.Item2, battery =>
                {
                    if (battery.SnowflakeId == 0) { return; }
                    Models.Devices.DeviceClientModel? device = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == context.TaskType
                    && x.DeviceType == context.DeviceType && x.Index == battery.Index);
                    if (device == null)
                    {
                        RunLog($"找不到[{battery.Index}]号设备", MessageLevelType.错误);
                        return;
                    }
                    RJ6902RResultModel rJ6902RResult = null;
                    try
                    {
                        RunLog($"-[{battery.Index}] 开始检测");
                        string status = string.Empty;
                        rJ6902RResult = device.Communication.ReadClass<RJ6902RResultModel>(0);
                    }
                    catch (Exception ex)
                    {
                        $"-[{battery.Index}] 获取结果时发生异常：{ex.ToString().Trim()}".RunLog(MessageLevelType.警告);
                    }
                    if (battery.SnowflakeId == -1)
                    {
                        RunLog($"-[{battery.Index}] 短路测试仪点检 地址：{battery.Address_Struct}");
                        WriteResult("",rJ6902RResult == null ? ResultTypes.不合格 : ResultTypes.合格, plc, battery.Address_Struct, context);
                        return;
                    }
                    if (rJ6902RResult == null)
                    {
                        $"-[{battery.Index}] 采集数据异常".RunLog(MessageLevelType.警告);
                        WriteResult("",ResultTypes.不合格, plc, battery.Address_Struct, context);
                        return;
                    }
                    DateTime dateTime = DateTime.Now;
                    ProductionData? entity = _temporaryStatic.EntityCache.FirstOrDefault(x => x.SnowflakeId == battery.SnowflakeId);
                    if (entity == null)
                    {
                        RunLog($"-[{battery.Index}] 实体缓存查询不到==>[{battery.SnowflakeId}]，转到数据库查询");
                        entity = dateTime.GetEntity(context.TaskType, battery.SnowflakeId);
                    }
                    else
                    {
                        ProductionData.Meta.TableName = entity.Items["TableName"].ToString();
                    }
                    if (entity == null)
                    {
                        RunLog($"-[{battery.Index}] 数据库找不到ID为：{battery.SnowflakeId}");
                        WriteResult("",ResultTypes.数据库找不到电池, plc, battery.Address_Struct, context);
                        return;
                    }
                    RunLog($"-[{battery.Index}] ID：[{battery.SnowflakeId}] 条码：[{entity.BarCode}]");
                    entity.LocationShortCircuitTester = battery.Index;
                    switch (battery.Data_PLC)
                    {
                        case 1:
                            entity.TimeElectrodes = dateTime.GetJSTimeUtc();
                            entity.ResistanceTestValue = rJ6902RResult.电阻测试数据;
                            entity.BoostTime = rJ6902RResult.升压时间 / 10.00;
                            entity.FallOne = rJ6902RResult.跌落1;
                            entity.FallTwo = rJ6902RResult.跌落2;
                            entity.ShellShortCicuteVoltage = rJ6902RResult.VP电压;
                            if (rJ6902RResult.总结果 == 1)
                            {
                                entity.ResultShortCicute =  ResultTypes.合格;
                                //if (!RangeCheck(entity.ResistanceTestValue, entity.RangeElectrodes) && _parameterStatic.DecideParameter.EnableResistance)
                                //{
                                //    entity.ResultShortCicute = entity.ResultTotal = ResultTypes.电极超范围;
                                //    Interlocked.Increment(ref _ngShortCircuit);
                                //}
                            }
                            else
                            {
                                Interlocked.Increment(ref _ngShortCircuit);
                                byte[] result = new byte[] { rJ6902RResult.开路结果, rJ6902RResult.严重短路结果,
                                          rJ6902RResult.欠压结果, rJ6902RResult.过压结果,
                                          rJ6902RResult.跌落1结果, rJ6902RResult.跌落2结果,
                                      rJ6902RResult.TL结果, rJ6902RResult.TH结果, rJ6902RResult.电阻测试结果};
                                int enum_result = -1;
                                for (int i = 0; i < result.Length; i++)
                                {
                                    if (result[i] != 1)
                                    {
                                        enum_result = (i + 1);
                                        break;
                                    }
                                }
                                //for (int i = 0; i < 9; i++)
                                //{
                                //    if (result[i] == 0xff)
                                //    {
                                //        entity.ResultShortCicute = (ShortCircuitAlarmCode)(i + 1);
                                //        break;
                                //    }
                                //}
                                enum_result = entity.ResultShortCicute.GetHashCode();
                                entity.ResultTotal = enum_result < 7 ? ResultTypes.Hi_Pot电压NG : ((enum_result > 6 && enum_result < 9) ? ResultTypes.Hi_Pot时间NG : ResultTypes.Hi_Pot阻值NG);                        
                            }
                            break;
                        case 2:
                            //entity.TimeHousing = dateTime.GetJSTimeUtc();
                            //entity.ResistanceTestValue = 88;
                            //entity.ResultHousing = ResultTypes.合格;
                            //if (entity.ResultHousing != ResultTypes.合格 && entity.ResultTotal == ResultTypes._)
                            //{
                            //    entity.ResultTotal = entity.ResultHousing;
                            //    Interlocked.Increment(ref _ngShortCircuit);
                            //}
                            //if (entity.ResultTotal == ResultTypes._ && !RangeCheck(entity.ResistanceTestValue, entity.RangeHousing))
                            //{
                            //    entity.ResultTotal = ResultTypes.壳体超范围;
                            //    Interlocked.Increment(ref _ngShortCircuit);
                            //}
                            break;
                    }
                    try
                    {
                        entity.Update();
                        _homeStatic.AddShortCircuitBattery(entity.BarCode, entity);
                    }
                    catch (Exception ex)
                    {
                        RunLog($"-[{battery.Index}] [{(battery.Data_PLC == 1 ? "电极" : "壳体")}] 更新数据异常：{ex}");
                    }
                    if (_parameterStatic.DecideParameter.EnableEmptyRun)
                    {
                        RunLog($"-[{battery.Index}] 启用空跑模式==>{entity.BarCode} 强制合格");
                        entity.ResultTotal = ResultTypes._;
                    }
                    WriteResult(entity.BarCode,entity.ResultTotal != ResultTypes._ ? entity.ResultTotal : ResultTypes.合格, plc, battery.Address_Struct, context);
                });
                _homeStatic.ChartData.NG_ShortCircuit += _ngShortCircuit;
                return base.Handle(context);
            }
            catch (Exception ex)
            {
                RunLog($"任务异常==>{ex}");
            }
            return Task.CompletedTask;
        }

        private bool RangeCheck(double value, string range)
        {
            string[] str = range.Split('=');
            double up = double.Parse(str[0]);
            double down = double.Parse(str[1]);
            return value <= up && value >= down;
        }

        private bool Cmd_Execute(byte[] cmd, Models.Devices.DeviceClientModel com, int index, string cmd_name, Func<string, bool> condition)
        {
            com.Communication.WriteSingle(cmd, 0, 0, 0);
            Thread.Sleep(50);
            byte[] bytes = com.Communication.ReadSingle<byte[]>(0, 0);
            if (bytes != null)
            {
                RunLog($"-[{index}] {cmd_name} 仪器返回：{BitConverter.ToString(bytes)}");
            }
            return false;
        }
    }
}
